#include "COverlord.h"

#include "core/loncore.h"

#include "CMinion.h"

COverlord::COverlord()
{

}

COverlord::~COverlord()
{
  stringc temp = login;
  cout << "COverlord of login: \"" << temp.c_str() << "\" has been deleted." << endl;
}

COverlord::COverlord(stringw login, stringw name, u8 type, u16 title, u16 fame)
{
  this->login = login;
  this->name = name;
  this->type = type;
  this->title = title;
  this->fame = fame;
}

COverlord::COverlord(stringw login)
{
  this->login = login;
}

COverlord::COverlord(SColor color)
{
  teamColor = color;
}

void COverlord::addMinion(CMinion* pMinion)
{
  vMinion.push_back(pMinion);
}

CMinion * COverlord::getMinion(int index)
{
  return vMinion[index];
}

u32 COverlord::getMinionIndex(int minion_id)
{
  for (u32 index = 0; index < vMinion.size(); index++)
  {
    CMinion *minion = vMinion[index];
    if (minion->minion_id() == minion_id)
      return index;
  }
  return 0;
}

void COverlord::removeMinion(int index)
{
  CMinion *temp = vMinion[index];
  delete temp;
  vMinion.erase(vMinion.begin()+index);
}

SColor COverlord::getTeamColor()
{
  return teamColor;
}

u32 COverlord::getID ()
{
  return ID;
}

stringw COverlord::getLogin()
{
  return login;
}

stringw COverlord::getName()
{
  return name;
}

u8 COverlord::getType()
{
  return type;
}

u16 COverlord::getTitle()
{
  return title;
}

u16 COverlord::getFame()
{
  return fame;
}

void COverlord::setID (u32 ID)
{
  this->ID = ID;
}

void COverlord::setPassword(stringw &password)
{
  this->password = password;
}

void COverlord::setTeamColor(SColor color)
{
  this->teamColor = color;
}

COverlord* COverlord::playerLogin(const char *username, const char *password)
{
  COverlord *player;

  CDalOverlord dalOverlord;
  CDalRecord &result =*(dalOverlord.getPlayerData(username));

  // No player found
  if (result.getRowCount() == 0)
  {
    std::cout << "Username : " << username << " not found." << std::endl;
    return 0;
  }
  else if (result.getRowCount() > 1)
  {
    std::cerr << "FATAL ERROR: Duplicate username in table `player`" << std::endl;
  }

  result.readNext();
  stringc pwDatabase = result.getString("password");
  stringc pwInput = password;

  if (pwInput == password)
  {
    player = new COverlord(username);
    player->password = password;

    // Retrive overlord record
    player->name = result.getString("player_name");
    player->type = result.getInt("overlord_type_code");
    player->title= result.getInt("overlord_title_code");
    player->fame = result.getInt("fame");
    player->player_id_ = result.getInt("player_id");
    player->win_ = result.getInt("win_count");
    player->lose_ = result.getInt("lose_count");
    delete &result;

    // Retrive overlord's minion records

    CDalRecord &rMinion = *(dalOverlord.getMinionDataByPlayerId(player->player_id_));
    while(rMinion.readNext())
    {
      minionStats stats;
      stats.name = rMinion.getString("minion_name");

      int minion_type_id = rMinion.getInt("minion_type_id");
      stats.typeName = CMinion::minion_base[minion_type_id].typeName;

      stats.hp = stats.maxHp = rMinion.getInt("hp");
      stats.mp = stats.maxMp = rMinion.getInt("mp");
      stats.atk = rMinion.getInt("attack");
      stats.mAtk = rMinion.getInt("magic_attack");
      stats.def = rMinion.getInt("defense");
      stats.mDef = rMinion.getInt("magic_defense");
      stats.speed = rMinion.getInt("speed");
      stats.level = rMinion.getInt("level");
      stats.range = rMinion.getDouble("range");
      stats.movement = rMinion.getDouble("movement");

      //stats.displayStats(); // Debug

      CMinion *minion = new CMinion(stats);
      minion->set_minion_id(rMinion.getInt("minion_id"));
      player->addMinion(minion);
    }
    delete &rMinion;

    // All data loaded. Returns the player
    return player;
  }
  return 0;
}

void COverlord::netWrite(BitStream &bs)
{
  // Convert the text into binary data for bitstream transfer
  CNetworkIO::writeWcs(bs, login.c_str());
  CNetworkIO::writeWcs(bs, name.c_str());

  bs.Write(player_id_);
  bs.Write(type);
  bs.Write(title);
  bs.Write(fame);
  bs.Write(win_);
  bs.Write(lose_);
}

void COverlord::netRead(BitStream &bs)
{
  login = CNetworkIO::readWcs(bs);
  name  = CNetworkIO::readWcs(bs);

  bs.Read(player_id_);
  bs.Read(type);
  bs.Read(title);
  bs.Read(fame);
  bs.Read(win_);
  bs.Read(lose_);
}
